home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / Verify.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  15KB  |  851 lines

  1. /*
  2. **    Verify.c
  3. **
  4. **    Check if files/drawers/programs are where they should be
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. struct Path
  17. {
  18.     BPTR path_Next,path_Lock;
  19. };
  20.  
  21.     /* FindPath(struct Window *Parent,STRPTR Path,BOOL CanCreate,LONG *Error):
  22.      *
  23.      *    For the complete path of a file, this checks if the
  24.      *    path leading to the file actually exists. This is
  25.      *    primarily for files the program should create. Thus,
  26.      *    the file in question may not yet exist.
  27.      */
  28.  
  29. BOOL
  30. FindPath(struct Window *Parent,STRPTR Path,BOOL CanCreate,LONG *Error)
  31. {
  32.     UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
  33.     STRPTR Index;
  34.  
  35.     strcpy(LocalBuffer,Path);
  36.  
  37.     Index = PathPart(LocalBuffer);
  38.  
  39.     *Index = 0;
  40.  
  41.     return(FindDrawer(Parent,LocalBuffer,CanCreate,Error));
  42. }
  43.  
  44.     /* FindDrawer(struct Window *Parent,STRPTR Drawer,BOOL CanCreate,LONG *Error):
  45.      *
  46.      *    Check if a given drawer exists and give
  47.      *    the user the choice to create it if necessary.
  48.      */
  49.  
  50. BOOL
  51. FindDrawer(struct Window *Parent,STRPTR Drawer,BOOL CanCreate,LONG *Error)
  52. {
  53.     LONG LocalError;
  54.     BPTR FileLock;
  55.     BOOL Result;
  56.     APTR OldPtr;
  57.  
  58.     if(!Config->MiscConfig->ProtectiveMode)
  59.         return(TRUE);
  60.  
  61.     Result = FALSE;
  62.  
  63.     if(!Error)
  64.         Error = &LocalError;
  65.  
  66.         /* Lock out DOS requesters */
  67.  
  68.     DisableDOSRequesters(&OldPtr);
  69.  
  70.         /* Does the drawer exist? */
  71.  
  72.     if(FileLock = Lock(Drawer,ACCESS_READ))
  73.     {
  74.         D_S(struct FileInfoBlock,FileInfo);
  75.  
  76.             /* Take a closer look */
  77.  
  78.         if(Examine(FileLock,FileInfo))
  79.         {
  80.                 /* Is this actually a file? */
  81.  
  82.             if(FileInfo->fib_DirEntryType < 0)
  83.                 *Error = ERR_NOT_A_DRAWER;
  84.             else
  85.             {
  86.                 *Error = 0;
  87.  
  88.                 Result = TRUE;
  89.             }
  90.         }
  91.         else
  92.             *Error = IoErr();
  93.  
  94.         UnLock(FileLock);
  95.     }
  96.     else
  97.     {
  98.         LONG Result2 = IoErr();
  99.  
  100.             /* If it doesn't exist, see if we should ask the user to create it */
  101.  
  102.         if(Result2 == ERROR_OBJECT_NOT_FOUND && Parent && CanCreate)
  103.         {
  104.             UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
  105.             BOOL LocalCanCreate;
  106.             STRPTR Index;
  107.  
  108.             LocalCanCreate = FALSE;
  109.  
  110.                 /* Chop off the last path part */
  111.  
  112.             strcpy(LocalBuffer,Drawer);
  113.  
  114.             Index = PathPart(LocalBuffer);
  115.  
  116.             *Index = 0;
  117.  
  118.                 /* Get a lock on the parent drawer */
  119.  
  120.             if(FileLock = Lock(LocalBuffer,ACCESS_READ))
  121.             {
  122.                 D_S(struct InfoData,InfoData);
  123.  
  124.                     /* Inquire volume information */
  125.  
  126.                 if(Info(FileLock,InfoData))
  127.                 {
  128.                         /* Can we write to this volume? */
  129.  
  130.                     if(InfoData->id_DiskState == ID_VALIDATED)
  131.                         LocalCanCreate = TRUE;
  132.                 }
  133.  
  134.                 UnLock(FileLock);
  135.             }
  136.  
  137.                 /* Give it a try? */
  138.  
  139.             if(LocalCanCreate)
  140.             {
  141.                 LT_LockWindow(Parent);
  142.  
  143.                     /* Ask if we should create it */
  144.  
  145.                 if(ShowRequest(Parent,LocaleString(MSG_VERIFY_NO_DRAWER_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Drawer))
  146.                 {
  147.                     if(FileLock = CreateDir(Drawer))
  148.                     {
  149.                         Result2 = 0;
  150.  
  151.                         Result = TRUE;
  152.  
  153.                         UnLock(FileLock);
  154.                     }
  155.                     else
  156.                         Result2 = IoErr();
  157.                 }
  158.                 else
  159.                 {
  160.                     Result2 = 0;
  161.                     Result = TRUE;
  162.                 }
  163.  
  164.                 LT_UnlockWindow(Parent);
  165.             }
  166.         }
  167.  
  168.         *Error = Result2;
  169.     }
  170.  
  171.     EnableDOSRequesters(OldPtr);
  172.  
  173.     if(Window && !Result && *Error)
  174.     {
  175.         LT_LockWindow(Parent);
  176.  
  177.         if(*Error == ERR_NOT_A_DRAWER)
  178.             ShowError(Parent,*Error,NULL,Drawer);
  179.         else
  180.             ShowError(Parent,ERR_DRAWER_NOT_FOUND,*Error,Drawer);
  181.  
  182.         LT_UnlockWindow(Parent);
  183.     }
  184.  
  185.     return(Result);
  186. }
  187.  
  188.     /* FindFile(struct Window *Parent,STRPTR File,LONG *Error):
  189.      *
  190.      *    Try to locate a file.
  191.      */
  192.  
  193. BOOL
  194. FindFile(struct Window *Parent,STRPTR File,LONG *Error)
  195. {
  196.     LONG LocalError;
  197.     BPTR FileLock;
  198.     BOOL Result;
  199.     APTR OldPtr;
  200.  
  201.     if(!Config->MiscConfig->ProtectiveMode)
  202.         return(TRUE);
  203.  
  204.     Result = FALSE;
  205.  
  206.     if(!Error)
  207.         Error = &LocalError;
  208.  
  209.         /* Lock out DOS requesters */
  210.  
  211.     DisableDOSRequesters(&OldPtr);
  212.  
  213.         /* Try to get a lock on the file */
  214.  
  215.     if(FileLock = Lock(File,ACCESS_READ))
  216.     {
  217.         D_S(struct FileInfoBlock,FileInfo);
  218.  
  219.             /* Take a closer look */
  220.  
  221.         if(Examine(FileLock,FileInfo))
  222.         {
  223.                 /* Is it actually a drawer? */
  224.  
  225.             if(FileInfo->fib_DirEntryType > 0)
  226.                 *Error = ERR_NOT_A_FILE;
  227.             else
  228.             {
  229.                 *Error = 0;
  230.  
  231.                 Result = TRUE;
  232.             }
  233.         }
  234.         else
  235.             *Error = IoErr();
  236.  
  237.         UnLock(FileLock);
  238.     }
  239.     else
  240.         *Error = IoErr();
  241.  
  242.     EnableDOSRequesters(OldPtr);
  243.  
  244.     if(Window && !Result && *Error)
  245.     {
  246.         LT_LockWindow(Parent);
  247.  
  248.         if(*Error == ERR_NOT_A_FILE)
  249.             ShowError(Parent,*Error,NULL,File);
  250.         else
  251.             ShowError(Parent,ERR_FILE_NOT_FOUND,*Error,File);
  252.  
  253.         LT_UnlockWindow(Parent);
  254.     }
  255.  
  256.     return(Result);
  257. }
  258.  
  259.     /* FindARexxComment(STRPTR LocalBuffer,LONG Len):
  260.      *
  261.      *    Check for a valid ARexx file comment.
  262.      */
  263.  
  264. STATIC BOOL
  265. FindARexxComment(STRPTR LocalBuffer,LONG Len)
  266. {
  267.     UBYTE c;
  268.     LONG i;
  269.  
  270.     for(i = 0 ; i < Len - 1 ; i++)
  271.     {
  272.         c = LocalBuffer[i];
  273.  
  274.             /* Stop on invalid characters. */
  275.  
  276.         if((c < ' ' && c != '\r' && c != '\n' && c != '\a') || (c >= 127 && c < 160))
  277.             break;
  278.         else
  279.         {
  280.                 /* Looks like the typical */
  281.                 /* introductory comment line. */
  282.  
  283.             if(c == '/' && LocalBuffer[i + 1] == '*')
  284.                 return(TRUE);
  285.         }
  286.     }
  287.  
  288.     return(FALSE);
  289. }
  290.  
  291.     /* FindProgram(struct Window *Parent,STRPTR Program,LONG *Error):
  292.      *
  293.      *    Try to find a program given by name. Firstly, try to access the
  294.      *    file by its name. If unsuccessful, search the Shell path list.
  295.      *    As a last resort, search the global AmigaDOS resident program
  296.      *    list. Note that while this routine may fail program execution
  297.      *    may still work. WShell for example maintains its own internal
  298.      *    resident list.
  299.      */
  300.  
  301. BOOL
  302. FindProgram(struct Window *Parent,STRPTR Program,LONG *Error)
  303. {
  304.     UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
  305.     BOOL Result,CanExecute;
  306.     LONG LocalError;
  307.     BPTR FileLock;
  308.     APTR OldPtr;
  309.     LONG i;
  310.  
  311.     if(!Config->MiscConfig->ProtectiveMode)
  312.         return(TRUE);
  313.  
  314.     Result        = FALSE;
  315.     CanExecute    = FALSE;
  316.  
  317.     if(!Error)
  318.         Error = &LocalError;
  319.  
  320.         /* Chop off the program arguments */
  321.  
  322.     while(*Program == ' ')
  323.         Program++;
  324.  
  325.     strcpy(LocalBuffer,Program);
  326.  
  327.     for(i = 0 ; i < strlen(LocalBuffer) ; i++)
  328.     {
  329.         if(LocalBuffer[i] == ' ')
  330.         {
  331.             LocalBuffer[i] = 0;
  332.             break;
  333.         }
  334.     }
  335.  
  336.     Program = LocalBuffer;
  337.  
  338.         /* Lock out DOS requesters */
  339.  
  340.     DisableDOSRequesters(&OldPtr);
  341.  
  342.         /* Try to lock the program */
  343.  
  344.     if(FileLock = Lock(Program,ACCESS_READ))
  345.     {
  346.         D_S(struct FileInfoBlock,FileInfo);
  347.  
  348.             /* Take a closer look */
  349.  
  350.         if(Examine(FileLock,FileInfo))
  351.         {
  352.                 /* Is it actually a drawer? */
  353.  
  354.             if(FileInfo->fib_DirEntryType > 0)
  355.                 *Error = ERR_NOT_A_FILE;
  356.             else
  357.             {
  358.                 BOOL GotIt;
  359.  
  360.                     /* So far, so good */
  361.  
  362.                 *Error = 0;
  363.  
  364.                 Result    = TRUE;
  365.                 GotIt    = FALSE;
  366.  
  367.                     /* Is it marked as being executable? */
  368.  
  369.                 if(!(FileInfo->fib_Protection & FIBF_EXECUTE))
  370.                 {
  371.                     BPTR FileHandle;
  372.                     ULONG Value;
  373.  
  374.                         /* Look at the contents */
  375.  
  376.                     if(FileHandle = Open(Program,MODE_OLDFILE))
  377.                     {
  378.                         if(Read(FileHandle,&Value,sizeof(ULONG)) == sizeof(ULONG))
  379.                         {
  380.                                 /* Not a failproof check, but better than nothing */
  381.  
  382.                             if(Value == HUNK_HEADER)
  383.                             {
  384.                                 CanExecute = TRUE;
  385.                                 GotIt = TRUE;
  386.                             }
  387.                         }
  388.  
  389.                         Close(FileHandle);
  390.                     }
  391.                 }
  392.  
  393.                 if(!GotIt)
  394.                 {
  395.                         /* Does it have the script bit set? */
  396.  
  397.                     if(FileInfo->fib_Protection & FIBF_SCRIPT)
  398.                         CanExecute = TRUE;
  399.                     else
  400.                     {
  401.                         BPTR FileHandle;
  402.  
  403.                             /* Now check if it's an ARexx script. */
  404.  
  405.                         if(FileHandle = Open(Program,MODE_OLDFILE))
  406.                         {
  407.                             UBYTE LocalBuffer[256];
  408.                             LONG Len;
  409.  
  410.                             if((Len = Read(FileHandle,LocalBuffer,sizeof(LocalBuffer))) > 0)
  411.                             {
  412.                                 if(CanExecute = FindARexxComment(LocalBuffer,Len))
  413.                                     Result = TRUE;
  414.                             }
  415.  
  416.                             Close(FileHandle);
  417.                         }
  418.                     }
  419.                 }
  420.             }
  421.         }
  422.  
  423.         UnLock(FileLock);
  424.     }
  425.     else
  426.     {
  427.         LONG Result2 = IoErr();
  428.  
  429.         if(Result2 == ERROR_DEVICE_NOT_MOUNTED)
  430.             *Error = ERROR_OBJECT_NOT_FOUND;
  431.         else
  432.             *Error = Result2;
  433.     }
  434.  
  435.         /* Give it another try */
  436.  
  437.     if(!Result || !CanExecute)
  438.     {
  439.             /* Take care */
  440.  
  441.         if(ThisProcess->pr_CLI)
  442.         {
  443.             struct CommandLineInterface    *CLI;
  444.             BOOL InitialCD,GotIt;
  445.             BPTR StartCD,Drawer;
  446.             struct Path *Path;
  447.  
  448.             CLI            = BADDR(ThisProcess->pr_CLI);
  449.             InitialCD    = TRUE;
  450.             GotIt        = FALSE;
  451.  
  452.                 /* Run down the Shell path search list */
  453.  
  454.             for(Path = BADDR(CLI->cli_CommandDir) ; Path && !GotIt ; Path = BADDR(Path->path_Next))
  455.             {
  456.                 Drawer = CurrentDir(Path->path_Lock);
  457.  
  458.                 if(InitialCD)
  459.                 {
  460.                     StartCD        = Drawer;
  461.                     InitialCD    = FALSE;
  462.                 }
  463.  
  464.                     /* Try to lock the program */
  465.  
  466.                 if(FileLock = Lock(Program,ACCESS_READ))
  467.                 {
  468.                     D_S(struct FileInfoBlock,FileInfo);
  469.  
  470.                         /* Take a closer look */
  471.  
  472.                     if(Examine(FileLock,FileInfo))
  473.                     {
  474.                             /* Is this a file marked as being executable? */
  475.  
  476.                         if(FileInfo->fib_DirEntryType < 0)
  477.                         {
  478.                             if(!(FileInfo->fib_Protection & FIBF_EXECUTE))
  479.                             {
  480.                                 BPTR FileHandle;
  481.                                 ULONG Value;
  482.  
  483.                                     /* Look at the contents */
  484.  
  485.                                 if(FileHandle = Open(Program,MODE_OLDFILE))
  486.                                 {
  487.                                     if(Read(FileHandle,&Value,sizeof(ULONG)) == sizeof(ULONG))
  488.                                     {
  489.                                             /* Not a failproof check, but better than nothing */
  490.  
  491.                                         if(Value == HUNK_HEADER)
  492.                                             GotIt = TRUE;
  493.                                     }
  494.  
  495.                                     Close(FileHandle);
  496.                                 }
  497.                             }
  498.  
  499.                             if(!GotIt)
  500.                             {
  501.                                     /* Does it look like a script? */
  502.  
  503.                                 if(FileInfo->fib_Protection & FIBF_SCRIPT)
  504.                                     GotIt = TRUE;
  505.                                 else
  506.                                 {
  507.                                     BPTR FileHandle;
  508.  
  509.                                         /* Now check if it's an ARexx script. */
  510.  
  511.                                     if(FileHandle = Open(Program,MODE_OLDFILE))
  512.                                     {
  513.                                         UBYTE LocalBuffer[256];
  514.                                         LONG Len;
  515.  
  516.                                         if((Len = Read(FileHandle,LocalBuffer,sizeof(LocalBuffer))) > 0)
  517.                                         {
  518.                                             if(CanExecute = FindARexxComment(LocalBuffer,Len))
  519.                                                 GotIt = TRUE;
  520.                                         }
  521.  
  522.                                         Close(FileHandle);
  523.                                     }
  524.                                 }
  525.                             }
  526.                         }
  527.                     }
  528.  
  529.                     UnLock(FileLock);
  530.                 }
  531.             }
  532.  
  533.             if(!GotIt)
  534.             {
  535.                 BPTR CommandDir;
  536.  
  537.                 if(CommandDir = Lock("C:",ACCESS_READ))
  538.                 {
  539.                     Drawer = CurrentDir(CommandDir);
  540.  
  541.                     if(InitialCD)
  542.                     {
  543.                         StartCD        = Drawer;
  544.                         InitialCD    = FALSE;
  545.                     }
  546.  
  547.                         /* Try to lock the program */
  548.  
  549.                     if(FileLock = Lock(Program,ACCESS_READ))
  550.                     {
  551.                         D_S(struct FileInfoBlock,FileInfo);
  552.  
  553.                             /* Take a closer look */
  554.  
  555.                         if(Examine(FileLock,FileInfo))
  556.                         {
  557.                                 /* Is this a file marked as being executable? */
  558.  
  559.                             if(FileInfo->fib_DirEntryType < 0)
  560.                             {
  561.                                 if(!(FileInfo->fib_Protection & FIBF_EXECUTE))
  562.                                 {
  563.                                     BPTR FileHandle;
  564.                                     ULONG Value;
  565.  
  566.                                         /* Look at the contents */
  567.  
  568.                                     if(FileHandle = Open(Program,MODE_OLDFILE))
  569.                                     {
  570.                                         if(Read(FileHandle,&Value,sizeof(ULONG)) == sizeof(ULONG))
  571.                                         {
  572.                                                 /* Not a failproof check, but better than nothing */
  573.  
  574.                                             if(Value == HUNK_HEADER)
  575.                                                 GotIt = TRUE;
  576.                                         }
  577.  
  578.                                         Close(FileHandle);
  579.                                     }
  580.                                 }
  581.  
  582.                                 if(!GotIt)
  583.                                 {
  584.                                         /* Does it look like a script? */
  585.  
  586.                                     if(FileInfo->fib_Protection & FIBF_SCRIPT)
  587.                                         GotIt = TRUE;
  588.                                     else
  589.                                     {
  590.                                         BPTR FileHandle;
  591.  
  592.                                             /* Now check if it's an ARexx script. */
  593.  
  594.                                         if(FileHandle = Open(Program,MODE_OLDFILE))
  595.                                         {
  596.                                             UBYTE LocalBuffer[256];
  597.                                             LONG Len;
  598.  
  599.                                             if((Len = Read(FileHandle,LocalBuffer,sizeof(LocalBuffer))) > 0)
  600.                                             {
  601.                                                 if(CanExecute = FindARexxComment(LocalBuffer,Len))
  602.                                                     GotIt = TRUE;
  603.                                             }
  604.  
  605.                                             Close(FileHandle);
  606.                                         }
  607.                                     }
  608.                                 }
  609.                             }
  610.                         }
  611.  
  612.                         UnLock(FileLock);
  613.                     }
  614.  
  615.                     UnLock(CommandDir);
  616.                 }
  617.             }
  618.  
  619.             if(!InitialCD)
  620.                 CurrentDir(StartCD);
  621.  
  622.             if(GotIt)
  623.             {
  624.                 CanExecute = TRUE;
  625.  
  626.                 *Error = 0;
  627.  
  628.                 Result = TRUE;
  629.             }
  630.         }
  631.     }
  632.  
  633.         /* As a last resort, scan the resident program list */
  634.  
  635.     if(!Result)
  636.     {
  637.         Forbid();
  638.  
  639.         if(FindSegment(Program,NULL,DOSFALSE) || FindSegment(Program,NULL,DOSTRUE))
  640.         {
  641.             CanExecute = TRUE;
  642.  
  643.             *Error = 0;
  644.  
  645.             Result = TRUE;
  646.         }
  647.  
  648.         Permit();
  649.     }
  650.  
  651.         /* Last check for ARexx script. */
  652.  
  653.     if(!Result)
  654.     {
  655.         UBYTE RexxName[MAX_FILENAME_LENGTH];
  656.  
  657.         strcpy(RexxName,"REXX:");
  658.  
  659.         if(AddPart(RexxName,Program,sizeof(RexxName)))
  660.         {
  661.             BPTR FileHandle;
  662.  
  663.                 /* Now check if it's an ARexx script. */
  664.  
  665.             if(FileHandle = Open(RexxName,MODE_OLDFILE))
  666.             {
  667.                 UBYTE LocalBuffer[256];
  668.                 LONG Len;
  669.  
  670.                 if((Len = Read(FileHandle,LocalBuffer,sizeof(LocalBuffer))) > 0)
  671.                 {
  672.                     if(CanExecute = FindARexxComment(LocalBuffer,Len))
  673.                         Result = TRUE;
  674.                 }
  675.  
  676.                 Close(FileHandle);
  677.             }
  678.         }
  679.     }
  680.  
  681.         /* Last check for AmigaDOS script */
  682.  
  683.     if(!Result)
  684.     {
  685.         UBYTE ScriptName[MAX_FILENAME_LENGTH];
  686.  
  687.         strcpy(ScriptName,"S:");
  688.  
  689.         if(AddPart(ScriptName,Program,sizeof(ScriptName)))
  690.         {
  691.             if(FileLock = Lock(ScriptName,ACCESS_READ))
  692.             {
  693.                 D_S(struct FileInfoBlock,FileInfo);
  694.  
  695.                 if(Examine(FileLock,FileInfo))
  696.                 {
  697.                     if(FileInfo->fib_DirEntryType < 0 && (FileInfo->fib_Protection & FIBF_SCRIPT) && FileInfo->fib_Size > 0)
  698.                         CanExecute = Result = TRUE;
  699.                 }
  700.  
  701.                 UnLock(FileLock);
  702.             }
  703.         }
  704.     }
  705.  
  706.     if(!CanExecute && Result)
  707.     {
  708.         *Error = ERROR_NOT_EXECUTABLE;
  709.  
  710.         Result = FALSE;
  711.     }
  712.  
  713.     EnableDOSRequesters(OldPtr);
  714.  
  715.     if(Window && !Result && *Error)
  716.     {
  717.         LT_LockWindow(Parent);
  718.  
  719.         if(*Error == ERR_NOT_A_FILE)
  720.             ShowError(Parent,*Error,NULL,Program);
  721.         else
  722.             ShowError(Parent,ERR_PROGRAM_NOT_FOUND,*Error,Program);
  723.  
  724.         LT_UnlockWindow(Parent);
  725.     }
  726.  
  727.     return(Result);
  728. }
  729.  
  730.     /* FindLibDev(struct Window *Parent,STRPTR File,LONG Type,LONG *Error):
  731.      *
  732.      *    Try to locate a file.
  733.      */
  734.  
  735. BOOL
  736. FindLibDev(struct Window *Parent,STRPTR File,LONG Type,LONG *Error)
  737. {
  738.     UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
  739.     BOOL Result,Replaced;
  740.     STRPTR OriginalFile;
  741.     struct Node    *Node;
  742.     LONG LocalError;
  743.     BPTR FileLock;
  744.     APTR OldPtr;
  745.     BOOL NotDone;
  746.  
  747.     if(!Config->MiscConfig->ProtectiveMode)
  748.         return(TRUE);
  749.  
  750.     Result        = FALSE;
  751.     Replaced    = FALSE;
  752.  
  753.     if(!Error)
  754.         Error = &LocalError;
  755.  
  756.     Forbid();
  757.  
  758.     if(Type == NT_LIBRARY)
  759.         Node = FindName(&SysBase->LibList,PathPart(File));
  760.     else
  761.         Node = FindName(&SysBase->DeviceList,PathPart(File));
  762.  
  763.     Permit();
  764.  
  765.     if(Node)
  766.     {
  767.         *Error = 0;
  768.  
  769.         return(TRUE);
  770.     }
  771.  
  772.         /* Lock out DOS requesters */
  773.  
  774.     DisableDOSRequesters(&OldPtr);
  775.  
  776.     do
  777.     {
  778.         NotDone = FALSE;
  779.  
  780.             /* Try to get a lock on the file */
  781.  
  782.         if(FileLock = Lock(File,ACCESS_READ))
  783.         {
  784.             D_S(struct FileInfoBlock,FileInfo);
  785.  
  786.                 /* Take a closer look */
  787.  
  788.             if(Examine(FileLock,FileInfo))
  789.             {
  790.                     /* Is it actually a drawer? */
  791.  
  792.                 if(FileInfo->fib_DirEntryType > 0)
  793.                     *Error = ERR_NOT_A_FILE;
  794.                 else
  795.                 {
  796.                     if(ValidateFile(File,Type,NULL))
  797.                     {
  798.                         *Error = 0;
  799.  
  800.                         Result = TRUE;
  801.                     }
  802.                     else
  803.                         *Error = ERROR_OBJECT_WRONG_TYPE;
  804.                 }
  805.             }
  806.             else
  807.                 *Error = IoErr();
  808.  
  809.             UnLock(FileLock);
  810.         }
  811.         else
  812.             *Error = IoErr();
  813.  
  814.         if(!Result && !Replaced)
  815.         {
  816.             Replaced = TRUE;
  817.  
  818.             strcpy(LocalBuffer,Type == NT_LIBRARY ? "Libs:" : "Devs:");
  819.  
  820.             OriginalFile = File;
  821.  
  822.             if(AddPart(LocalBuffer,File,sizeof(LocalBuffer)))
  823.             {
  824.                 File = LocalBuffer;
  825.  
  826.                 NotDone = TRUE;
  827.             }
  828.         }
  829.     }
  830.     while(NotDone);
  831.  
  832.     if(Replaced)
  833.         File = OriginalFile;
  834.  
  835.     EnableDOSRequesters(OldPtr);
  836.  
  837.     if(Window && !Result && *Error)
  838.     {
  839.         LT_LockWindow(Parent);
  840.  
  841.         if(*Error == ERR_NOT_A_FILE)
  842.             ShowError(Parent,*Error,NULL,File);
  843.         else
  844.             ShowError(Parent,ERR_FILE_NOT_FOUND,*Error,File);
  845.  
  846.         LT_UnlockWindow(Parent);
  847.     }
  848.  
  849.     return(Result);
  850. }
  851.